package com.ssy.lingxi.settle.accounts.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.dto.request.*;
import com.ssy.lingxi.dto.response.InvoiceMessageResponse;
import com.ssy.lingxi.settle.accounts.common.SettleAccountsCommon;
import com.ssy.lingxi.settle.accounts.entity.InvoiceMessage;
import com.ssy.lingxi.settle.accounts.model.constant.CommonBooleanEnum;
import com.ssy.lingxi.settle.accounts.repository.InvoiceMessageRepository;
import com.ssy.lingxi.settle.accounts.service.InvoiceMessageService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 发票信息管理
 * @author wrc
 * @date 2020/8/25
 */
@Service
public class InvoiceMessageServiceImpl implements InvoiceMessageService {

    @Resource
    InvoiceMessageRepository invoiceMessageRepository;

    @Override
    public Wrapper<List<InvoiceMessageResponse>> invoiceMessageList(UserLoginCacheDTO sysUser) {
        List<Sort.Order> orders = Arrays.asList(new Sort.Order(Sort.Direction.DESC, "isDefault"), new Sort.Order(Sort.Direction.DESC, "createTime"));
        List<InvoiceMessage> allByMemberIdEquals = invoiceMessageRepository.findAllByMemberIdEquals(sysUser.getMemberId(), Sort.by(orders));
        List<InvoiceMessageResponse> list = new ArrayList<>();
        if (null != allByMemberIdEquals && allByMemberIdEquals.size() > 0) {
            list = allByMemberIdEquals.stream().map(temp -> {
                InvoiceMessageResponse invoiceMessageResponse = new InvoiceMessageResponse();
                BeanUtils.copyProperties(temp, invoiceMessageResponse);
                return invoiceMessageResponse;
            }).collect(Collectors.toList());
        }
        return Wrapper.success(list);
    }

    /**
     * 添加发票信息
     * @author wrc
     * @date 2020/8/25
     */
    @Transactional
    @Override
    public Wrapper<Void> invoiceMessageAdd(InvoiceMessageAddRequest request, UserLoginCacheDTO sysUser) {
        InvoiceMessage invoiceMessage = new InvoiceMessage();
        BeanUtils.copyProperties(request, invoiceMessage);
        invoiceMessage.setCreateRoleId(sysUser.getMemberRoleId());
        invoiceMessage.setCreateTime(System.currentTimeMillis());
        invoiceMessage.setMemberId(sysUser.getMemberId());
        if (SettleAccountsCommon.IsDefault.YES.equals(request.getIsDefault())) {
            List<InvoiceMessage> allByIsDefaultAndMemberId = invoiceMessageRepository.findAllByIsDefaultAndMemberId(SettleAccountsCommon.IsDefault.YES, sysUser.getMemberId());
            if (null != allByIsDefaultAndMemberId && allByIsDefaultAndMemberId.size() > 0) {
                allByIsDefaultAndMemberId.forEach(v -> v.setIsDefault(SettleAccountsCommon.IsDefault.NOT));
                invoiceMessageRepository.saveAll(allByIsDefaultAndMemberId);
            }
        }
        invoiceMessageRepository.saveAndFlush(invoiceMessage);
        return Wrapper.success();
    }

    /**
     * 修改发票信息
     * @author wrc
     * @date 2020/8/26
     */
    @Transactional
    @Override
    public Wrapper<Void> invoiceMessageUpdate(InvoiceMessageUpdateRequest request, UserLoginCacheDTO sysUser) {
        Optional<InvoiceMessage> byId = invoiceMessageRepository.findById(request.getId());
        if (!byId.isPresent()) {
            return Wrapper.fail(ResponseCode.SETTLE_ACCOUNTS_DON_T_EXIST);
        }
        List<Sort.Order> orders = Arrays.asList(new Sort.Order(Sort.Direction.DESC, "isDefault"), new Sort.Order(Sort.Direction.DESC, "createTime"));
        List<InvoiceMessage> allByMemberIdEquals = invoiceMessageRepository.findAllByMemberIdEquals(sysUser.getMemberId(), Sort.by(orders));
        InvoiceMessage invoiceMessage = byId.get();
        invoiceMessage.setUpdateTime(System.currentTimeMillis());
        invoiceMessage.setType(request.getType());
        invoiceMessage.setTel(request.getTel());
        invoiceMessage.setTaxNo(request.getTaxNo());
        invoiceMessage.setKind(request.getKind());
        invoiceMessage.setInvoiceTitle(request.getInvoiceTitle());
        invoiceMessage.setBankOfDeposit(request.getBankOfDeposit());
        invoiceMessage.setAddress(request.getAddress());
        invoiceMessage.setAccount(request.getAccount());
        if (SettleAccountsCommon.IsDefault.YES.equals(request.getIsDefault())) {
            List<InvoiceMessage> allByIsDefaultAndMemberId = invoiceMessageRepository.findAllByIsDefaultAndMemberId(SettleAccountsCommon.IsDefault.YES, sysUser.getMemberId());
            allByIsDefaultAndMemberId.forEach(v -> v.setIsDefault(SettleAccountsCommon.IsDefault.NOT));
            invoiceMessageRepository.saveAll(allByIsDefaultAndMemberId);
        } else {
            List<InvoiceMessage> allByIsDefaultAndMemberId = invoiceMessageRepository.findAllByIsDefaultAndMemberId(SettleAccountsCommon.IsDefault.YES, sysUser.getMemberId());
            if (null == allByIsDefaultAndMemberId || allByIsDefaultAndMemberId.size() == 0) {
                InvoiceMessage invoice = allByMemberIdEquals.get(0);
                invoice.setIsDefault(SettleAccountsCommon.IsDefault.YES);
                invoiceMessageRepository.saveAndFlush(invoice);
            }
        }
        invoiceMessage.setIsDefault(request.getIsDefault());
        invoiceMessageRepository.saveAndFlush(invoiceMessage);
        return Wrapper.success();
    }

    /**
     * 删除发票信息
     * @author wrc
     * @date 2020/8/26
     */
    @Override
    public Wrapper<Void> invoiceMessageDelete(InvoiceMessageDeleteRequest request, UserLoginCacheDTO sysUser) {
        Optional<InvoiceMessage> byId = invoiceMessageRepository.findById(request.getId());
        if (!byId.isPresent()) {
            return Wrapper.fail(ResponseCode.SETTLE_ACCOUNTS_DON_T_EXIST);
        }
        invoiceMessageRepository.deleteById(request.getId());
        return Wrapper.success();
    }

    /**
     * 查询发票详情
     * @author wrc
     * @date 2020/8/26
     */
    @Override
    public Wrapper<InvoiceMessageResponse> invoiceMessageDetails(InvoiceMessageDeleteRequest request) {
        Optional<InvoiceMessage> byId = invoiceMessageRepository.findById(request.getId());
        if (!byId.isPresent()) {
            return Wrapper.fail(ResponseCode.SETTLE_ACCOUNTS_DON_T_EXIST);
        }
        InvoiceMessage invoiceMessage = byId.get();
        InvoiceMessageResponse invoiceMessageResponse = new InvoiceMessageResponse();
        BeanUtils.copyProperties(invoiceMessage, invoiceMessageResponse);
        return Wrapper.success(invoiceMessageResponse);
    }

    /**
     * 查询默认发票
     * @author 伍将
     * @date 2021/2/4
     * @param request: 请求参数
     * @return 操作结果
     **/
    @Override
    public Wrapper<InvoiceMessageResponse> getDefaultInvoice(InvoiceMessageGetRequest request) {

        InvoiceMessageResponse result = null;
        InvoiceMessage invoiceMessage = invoiceMessageRepository.findByIsDefaultAndMemberIdAndCreateRoleId(CommonBooleanEnum.YES.getCode(), request.getMemberId(), request.getRoleId());
        if (null != invoiceMessage) {
            result = new InvoiceMessageResponse();
            BeanUtils.copyProperties(invoiceMessage, result);
        }

        return Wrapper.success(result);
    }

    @Override
    public Wrapper<List<InvoiceMessageResponse>> getMemberInvoiceMessageList(InvoiceMessageListRequest request) {
        Specification<InvoiceMessage> spec =  (root, query, criteriaBuilder) -> {
            List<Predicate> groupList=new ArrayList<>();
            List<Long> memberIds = request.getMemberList().stream().map(InvoiceMessageGetRequest::getMemberId).distinct().collect(Collectors.toList());
            groupList.add(criteriaBuilder.in(root.get("memberId")).value(memberIds));
            Predicate[] p = new Predicate[groupList.size()];
            return criteriaBuilder.and(groupList.toArray(p));
        };
        List<InvoiceMessage> list = invoiceMessageRepository.findAll(spec, Sort.by("isDefault").descending());

        if(CollectionUtil.isNotEmpty(list)){
            ArrayList<InvoiceMessage> collect = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(InvoiceMessage::getMemberId).thenComparing(InvoiceMessage::getCreateRoleId))), ArrayList::new));
            return Wrapper.success(collect.stream().map(o -> {
                InvoiceMessageResponse response = new InvoiceMessageResponse();
                BeanUtils.copyProperties(o, response);
                return response;
            }).collect(Collectors.toList()));
        }
        return Wrapper.success();
    }
}
